package com.adjy.pathbuilders.objects;

import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.contacts.Contact;

import com.adjy.pathbuilders.physics.MovementType;
import com.adjy.pathbuilders.physics.PhysicalObject;
import com.adjy.pathbuilders.rendering.AnimationPack;
import com.adjy.pathbuilders.sounds.SoundManager;
import com.adjy.pathbuilders.world.GameEntity;
import com.adjy.pathbuilders.world.GameWorld;
import com.adjy.pathbuilders.world.MainChar;

/**
 * Cloud class implements a GameEntity Cloud<br>
 * This Entity lifts the player when he touches it until a certain point, then
 * drops the player back and goes back to its initial position
 */
public class Cloud extends GameEntity implements Thinkable {
	
	public static final float[] SIZE = {5, 5}; // This size is used for scaling images
	private static final float[] RENDER_OFFSETS = {2.2f, 2.2f};

	private MovementType playerInitialMovement;
	private long initialCollisionTime = -1;
	private float initialY;
	
	private boolean enabled;
	private boolean isColliding;
	private MainChar playerAffected;

	private float floatDistance;
	
	// FIXME needs to be converted to the display size
	private static final float MAX_FLOAT_DISTANCE = 6;
	
	/**
	 * Constructor for a Cloud
	 * 
	 * @param x
	 *            X Position
	 * @param y
	 *            Y Position
	 * @param frame
	 *            Frame which it should be rendered
	 */
	public Cloud(float x, float y, AnimationPack ap) {
		// 20 and 25 are offsets
		super(GameEntityType.CLOUD,
				x, y,
				SIZE[0] - 4f, SIZE[1] - 4f, // 10, 10
				ap, false, false, true);
		
		setAnimation("cloud");
		setRenderOffsets(-RENDER_OFFSETS[0], RENDER_OFFSETS[1]);
		initialY = y;
		enabled = true;
		isColliding = false;
		floatDistance = 0;
	}

	@Override
	public void hasStartedCollidingWith(PhysicalObject pObject, Contact contact) {
		if (pObject == null)
			return;
		
		if (((GameEntity) pObject).getType() == GameEntityType.MAINCHAR && enabled) {
			
			MainChar c = (MainChar) pObject;
			isColliding = true;
			playerAffected = c;
			initialY = getBody().getPosition().y;
			
			if (playerInitialMovement == null) { // First Collision!
				SoundManager.getInstance().playSoundEffect("cloud");
				if (c.getMovementType() == MovementType.STOPPED)
					return; // Only works with the player is moving towards Cloud

				playerInitialMovement = c.getMovementType();
				initialCollisionTime = System.currentTimeMillis();
			}
			
			// Stop Player and its gravity effect
			c.setAffectedByGravity(false); // FIXME: does nothing...
			c.setMovementType(MovementType.STOPPED);

			// Go up!

			
		}
	}

	@Override
	public void think(GameWorld gameWorld, float timePassed) {
		if (!enabled) { // If disabled, goes back to its position
			if (getBody().getPosition().y > initialY) {
				getBody().setLinearVelocity(new Vec2(0, -10));
			} else {
				getBody().setLinearVelocity(new Vec2(0, 0));
				enabled = true;
			}
		} else if (enabled && !isColliding && initialCollisionTime != -1) {
			enabled = false;
			playerAffected.setMovementType(playerInitialMovement);
			playerAffected.setAffectedByGravity(true);
			// Resets
			playerInitialMovement = null;
			initialCollisionTime = -1;
			
		} else if (enabled && isColliding && initialCollisionTime != -1) {
			getBody().setLinearVelocity(new Vec2(0, 10));
			playerAffected.getBody().setLinearVelocity(new Vec2(0, 10));
			floatDistance += 10*timePassed;
			
			if (floatDistance > MAX_FLOAT_DISTANCE) {
				floatDistance = 0;
				// If
				// Expired
				// Disable it
				enabled = false;
				// Gives player back its movement
				playerAffected.setMovementType(playerInitialMovement);
				//c.setAffectedByGravity(true);
				// Resets
				playerInitialMovement = null;
				initialCollisionTime = -1;
			}
		}
	}
	
	@Override
	public void hasStoppedCollidingWith(PhysicalObject pObject, Contact contact) {
		if (pObject == null)
			return;
		// FIXME: if (player)
		if (((GameEntity) pObject).getType() == GameEntityType.MAINCHAR) {
			isColliding = false;
		}
	}
}
